package com.kinyx.framework.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.kinyx.framework.annotation.assist.CanNotNull;
import com.kinyx.framework.annotation.assist.CanNull;
import com.kinyx.framework.annotation.assist.ReturnNotNull;
import com.kinyx.framework.annotation.assist.ReturnNull;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 匹配工具类
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class KMatcherUtils {

	/** 匹配标志 */
	private static final int FLAGS = 0;
	/** 分组索引值 */
	private static final int GROUP = 0;

	/**
	 * 获取模板对象
	 * @param regex 正则表达式
	 * @param flags 匹配标志
	 * @return 模板对象
	 */
	@ReturnNotNull
	public static Pattern getPattern(@CanNotNull final String regex, @CanNotNull final int flags) {
		return Pattern.compile(regex, flags);
	}

	/**
	 * 获取模板对象
	 * @param regex 正则表达式
	 * @return 模板对象
	 */
	@ReturnNotNull
	public static Pattern getPattern(@CanNotNull final String regex) {
		return Pattern.compile(regex, FLAGS);
	}

	/**
	 * 获取匹配对象
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @param flags 匹配标志
	 * @return 匹配对象
	 */
	@ReturnNotNull
	public static Matcher getMatcher(@CanNotNull final String str, @CanNotNull final String regex, @CanNotNull final int flags) {
		return getPattern(regex, flags).matcher(str);
	}

	/**
	 * 获取匹配对象
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @return 匹配对象
	 */
	@ReturnNotNull
	public static Matcher getMatcher(@CanNotNull final String str, @CanNotNull final String regex) {
		return getPattern(regex, FLAGS).matcher(str);
	}

	/**
	 * 匹配字符串
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @param flags 匹配标志
	 * @return true: 匹配; false: 不匹配;
	 */
	@ReturnNotNull
	public static boolean matches(@CanNull final String str, @CanNull final String regex, @CanNotNull final int flags) {
		if ((str == null) || (regex == null)) { return false; }
		return getMatcher(str, regex, flags).matches();
	}

	/**
	 * 匹配字符串
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @return true: 匹配; false: 不匹配;
	 */
	@ReturnNotNull
	public static boolean matches(@CanNull final String str, @CanNull final String regex) {
		if ((str == null) || (regex == null)) { return false; }
		return getMatcher(str, regex, FLAGS).matches();
	}

	/**
	 * 提取匹配的字符串列表
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @param flags 匹配标志
	 * @param group 分组索引值
	 * @return 字符串列表
	 */
	@ReturnNotNull
	public static List<String> extract(@CanNull final String str, @CanNull final String regex, @CanNotNull final int flags, final int group) {
		if ((str == null) || (regex == null)) { return Collections.emptyList(); }
		final List<String> list = new ArrayList<>();
		final Matcher m = getMatcher(str, regex, flags);
		while (m.find()) { list.add(m.group(group)); }
		return list;
	}

	/**
	 * 提取匹配的字符串列表
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @return 字符串列表
	 */
	@ReturnNotNull
	public static List<String> extract(@CanNull final String str, @CanNull final String regex) {
		return extract(str, regex, FLAGS, GROUP);
	}

	/**
	 * 提取第一个匹配的字符串
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @param flags 匹配标志
	 * @param group 索引值
	 * @return 字符串
	 */
	@ReturnNull("str == null")
	@ReturnNull("regex == null")
	@ReturnNull("匹配不到结果")
	public static String extractFirst(@CanNull final String str, @CanNull final String regex, @CanNotNull final int flags, @CanNotNull final int group) {
		if ((str == null) || (regex == null)) { return null; }
		final Matcher m = getMatcher(str, regex, flags);
		while (m.find()) { return m.group(group); }
		return null;
	}

	/**
	 * 提取第一个匹配的字符串
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @return 字符串
	 */
	@ReturnNull("str == null")
	@ReturnNull("regex == null")
	@ReturnNull("匹配不到结果")
	public static String extractFirst(@CanNull final String str, @CanNull final String regex) {
		return extractFirst(str, regex, FLAGS, GROUP);
	}

	/**
	 * 统计匹配的字符串出现的次数
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @param flags 匹配标志
	 * @return 次数
	 */
	@ReturnNotNull
	public static int count(@CanNull final String str, @CanNull final String regex, @CanNotNull final int flags) {
		if ((str == null) || (regex == null)) { return 0; }
		int count = 0;
		final Matcher m = getMatcher(str, regex, flags);
		while (m.find()) { count++; }
		return count;
	}

	/**
	 * 统计匹配的字符串出现的次数
	 * @param str 字符串
	 * @param regex 正则表达式
	 * @return 次数
	 */
	@ReturnNotNull
	public static int count(@CanNull final String str, @CanNull final String regex) {
		return count(str, regex, FLAGS);
	}

}
